package com.yang.simple_rpc.server;

import com.yang.simple_rpc.common.protocol.MessageProtocol;
import com.yang.simple_rpc.common.protocol.SimpleRequest;
import com.yang.simple_rpc.common.protocol.SimpleResponse;
import com.yang.simple_rpc.common.protocol.SimpleStatus;
import com.yang.simple_rpc.server.register.ServiceObject;
import com.yang.simple_rpc.server.register.ServiceRegister;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author : morikawaaaa
 * @date : 2022
 */
public class RequestHandler {


    private MessageProtocol protocol;

    private ServiceRegister serviceRegister;

    public RequestHandler(MessageProtocol protocol, ServiceRegister serviceRegister){
        super();
        this.protocol = protocol;
        this.serviceRegister = serviceRegister;
    }

    public byte[] handleRequest(byte[] bytes) throws Exception{
        SimpleRequest sreq = this.protocol.unmarshallingRequest(bytes);

        ServiceObject so = this.serviceRegister.getServiceObject(sreq.getServiceName());

        SimpleResponse srsp = null;
        //不提供这个服务
        if(so == null){
            srsp = new SimpleResponse(SimpleStatus.NOT_FOUND);
        }else{
            try{
                //通过反射获取这个服务的方法,invoke在服务端调用方法
                Method m = so.getClazz().getMethod(sreq.getMethod(), sreq.getParameterTypes());
                Object returnValue = m.invoke(so.getObj(), sreq.getParameters());
                srsp = new SimpleResponse(SimpleStatus.SUCCESS);
                srsp.setReturnValue(returnValue);
            }catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e){
                srsp = new SimpleResponse(SimpleStatus.ERROR);
                srsp.setException(e);
            }

        }
        //编组响应的消息
        return this.protocol.marshallingResponse(srsp);
    }

    public MessageProtocol getProtocol() {
        return protocol;
    }

    public void setProtocol(MessageProtocol protocol) {
        this.protocol = protocol;
    }

    public ServiceRegister getServiceRegister() {
        return serviceRegister;
    }

    public void setServiceRegister(ServiceRegister serviceRegister) {
        this.serviceRegister = serviceRegister;
    }
}
